/**
 * 模板工具，读取某个文件模板，然后按照模板配置规则，
 * 根据传入内容，替换模板内容生成相应文件。
 * 用途：代码生成器
 * @author create by lms 2019.05.08
 */

package ms.core.tool;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TemplateTool {

	private static void replaceBlock(String tplBlock, Map<String, String> global, List<Map<String, String>> maps, StringBuilder writer) {
		String block = "";
		//替换需要循环的文本标签段
		if (maps!=null) {
			for(Map<String, String> map: maps) {
				block = block+tplBlock;
				for(Map.Entry<String, String> item: map.entrySet()) {
					block = block.replace(item.getKey(), item.getValue());
				}
			}
		} else {
			block = tplBlock;
		}
		//替换全局文本标签
		for(Map.Entry<String, String> item: global.entrySet()) {
			block = block.replace(item.getKey(), item.getValue());
		}
		//写入writer
		writer.append(block);
	}

	/**
	 * 依据模板文件，生成目标文件
	 * @param tplFile 模板文件
	 * @param destFile 目标文件
	 * @param values 标签内容
	 */
	public static boolean makeFile(String tplFile, String destFile, Map<String, String> global, List<Map<String, String>> list) {
		try {
			global.put("$<seperator>",System.lineSeparator());
			StringBuilder sbWriter = new StringBuilder();
			InputStream in = StreamTool.loadFileToStream(TemplateTool.class, tplFile);
			BufferedInputStream bis = new BufferedInputStream(in);
			BufferedReader tplReader = new BufferedReader(new InputStreamReader(bis, "utf-8"));

			while (tplReader.ready()) {
				String line = tplReader.readLine();
				StringBuilder block = new StringBuilder();
				//读取模板	
				if (line.contains("$<list>")) {//读取到循环标签
					while (tplReader.ready()) {
						line = tplReader.readLine();
						if (line.contains("$</list>")) break;
						block.append(line).append(System.lineSeparator());
					}
					replaceBlock(block.toString(), global, list, sbWriter);
				} else {//非循环标签
					block.append(line).append(System.lineSeparator());
					replaceBlock(block.toString(), global, null, sbWriter);
				}
			}
			
			in.close();
			bis.close();
			tplReader.close();

			return SysTool.writeTextFile(destFile, sbWriter.toString(), "utf-8");
		}catch(Exception e){			
			Log4j2Tool.error(TemplateTool.class, "makeFile:", e);
			return false;
		}
	}
	
	public static void main(String[] args) {
		Map<String, String> global = new HashMap<String, String>();
		global.put("${table}", "pallas_test");
		global.put("${company}", "HuiLin");
		global.put("${package}", "ms.core.test");
		global.put("${objName}", "PallasTest");
		global.put("${createDate}", DateTimeTool.dateToDateTimeString(new Date()));
		global.put("${author}", System.getenv("USERNAME"));

		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		Map<String, String> map = new HashMap<String, String>();
		map.put("${fieldType}", "int");
		map.put("${fieldName}", "id");
		map.put("${fieldNameEx}", "Id");
		map.put("${fieldDesc}", "记录id");
		list.add(map);

		map = new HashMap<String, String>();
		map.put("${fieldType}", "String");
		map.put("${fieldName}", "name");
		map.put("${fieldNameEx}", "Name");
		map.put("${fieldDesc}", "姓名");
		list.add(map);

		TemplateTool.makeFile("/tpl/service.tpl", "d:/abc.java", global, list);
	}
}
